package org.wenhuayuan.project.common.view

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import org.wenhuayuan.project.common.R
import org.wenhuayuan.uilibrary.hiitem.HiAdapter

class HiRecyclerView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet?, defStyleAttr: Int = 0) : RecyclerView(context, attrs, defStyleAttr) {

    private var loadMoreScrollListener: LoadMoreScrollListener? = null
    private var footerView:View? = null
    private var isMoreLoading = false
    // 根据当前的滑动状态 决定要不要添加footerview 要不要执行上拉加载分页的动作
    inner class LoadMoreScrollListener (val prefetchSize: Int, val callback: ()->Unit) : OnScrollListener() {
    private var iprefetchSize: Int = 6
        init {
            iprefetchSize = prefetchSize
        }

        // 这里强转，是因为前面有前置的检查
        val hiAdapter = adapter as HiAdapter
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {

            if (isMoreLoading) {
                return
            }

            // 判断当前列表上是否已经显示完全了 item 的个数，如果已经显示且item的数量=0
            val totalCount = hiAdapter.itemCount
            if (totalCount < 1) {
                return
            }

            // 判断此时滑动状态为拖动时，要不要添加footer
            // 目的是防止列表滑动到了列表底部，但是加载动画footer还没有显示出来
            // 1，依旧需要判断列表是否能继续向下滑动
            val canScrollVertical = recyclerView.canScrollHorizontally(1)
            // 2，还有一种清况，canScrollVertical是检查列表是否能够向下滑动。
            // 特殊清况下已经滑动到底部，但是分页失败，但依然要继续向上拉
            // 此时需要拿当前最后一个item的position 和 totalItemCount做比较
            val lastVisibleItemPosition : Int = findLastVisibleItem(recyclerView)

            val firstVisibleItemPosition : Int = findFirstVisibleItem(recyclerView)
            // 表示已经全部显示
            val isArriveBottom = lastVisibleItemPosition >= totalCount - 1 && firstVisibleItemPosition > 0
            if (lastVisibleItemPosition <= 0 ) {
                return
            }

            if (newState == RecyclerView.SCROLL_STATE_DRAGGING && (canScrollVertical || isArriveBottom)) {
                addFooterViewLoading()
            }

            // 不时在滑动停止后，才去添加footer
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                return
            }
            // 预加载效果,滑动到最后一个item时触发下一页的加载
            val isArrivePrefetchPosition = totalCount - lastVisibleItemPosition <= prefetchSize
            if (!isArrivePrefetchPosition) return

            isMoreLoading = true
            callback()

        }

        // 添加加载动画的view
        private fun addFooterViewLoading() {
            val footerView = getFooterView()
            // 踩坑：在一些边界场景下会出现多次添加的清况。添加之前要先remove，
            // 但是remove有一定的延迟，会导致add执行可能会在remove之前
            // 最终导致view重复添加的报错，解决如下：
            if (footerView.parent != null) {
                footerView.post { addFooterViewLoading() }
            } else {
                hiAdapter.addFooterView(footerView)
            }
            hiAdapter.addFooterView(footerView)
        }

        private fun getFooterView() : View {
            if (null == footerView) {
                footerView = LayoutInflater.from(context).inflate(R.layout.layout_footer_loading, this@HiRecyclerView, false)
            }
            return footerView!!
        }

        // 查找最后一个可见ItemView的position
        private fun findLastVisibleItem(recyclerView: RecyclerView): Int {
            return when(val layoutManager = recyclerView.layoutManager) {
                is LinearLayoutManager -> layoutManager.findLastVisibleItemPosition()
                is StaggeredGridLayoutManager -> layoutManager.findLastVisibleItemPositions(null)[0]
                else -> -1
            }
        }
        private fun findFirstVisibleItem(recyclerView: RecyclerView): Int {
            return when(val layoutManager = recyclerView.layoutManager) {
                is LinearLayoutManager -> layoutManager.findFirstVisibleItemPosition()
                is StaggeredGridLayoutManager -> layoutManager.findFirstVisibleItemPositions(null)[0]
                else -> -1
            }
        }

    }

    fun enableLoadMore(prefetchSize: Int, callback: ()-> Unit) {
        if (adapter !is HiAdapter) {
            Log.e("HiRecyclerView", "enableLoadMore must use hiAdapter")
            return
        }

        loadMoreScrollListener = LoadMoreScrollListener(prefetchSize, callback)
        addOnScrollListener(loadMoreScrollListener!!)
    }

    fun disableLoadMore() {
        if (adapter !is HiAdapter) {
            Log.e("HiRecyclerView", "enableLoadMore must use hiAdapter")
            return
        }
        val hiAdapter = adapter as HiAdapter
        footerView?.let {
            if (it.parent != null) {
                hiAdapter.removeFooterView(it)
            }
        }
        loadMoreScrollListener?.let {
            removeOnScrollListener(it)
            loadMoreScrollListener = null
            footerView = null
            isMoreLoading = false
        }
    }

    fun isLoadingMore () : Boolean {
        return isMoreLoading
    }

    fun loadingFinished (success: Boolean) {
        if (adapter !is HiAdapter) {
            Log.e("HiRecyclerView", "enableLoadMore must use hiAdapter")
            return
        }

        isMoreLoading = false
        val hiAdapter = adapter as HiAdapter
        if (!success) {
            footerView?.let {
                if (it.parent != null) {
                    hiAdapter.removeFooterView(it)
                }
            }
        } else {
//            isMoreLoading = true
        }

    }
}